package com.xzl.zuul.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.xxxx.server.utils.JwtUtils;
import com.xzl.tool.util.RespBean;
import com.xzl.zuul.service.LoginServerService;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 登陆过滤器
 */
@Component
public class LoginFilter extends ZuulFilter {
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private LoginServerService loginServerService;

    /**
     * 过滤器类型，前置过滤器
     *
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 过滤器顺序，越小越先执行
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 4;
    }

    /**
     * 过滤器是否生效
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 业务逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        JwtUtils jwtUtils = new JwtUtils();
        RequestContext requestContext = RequestContext.getCurrentContext();
        // 获取当前请求和返回值
        HttpServletRequest request = requestContext.getRequest();
        HttpServletResponse response = requestContext.getResponse();
        //从请求头里获取token对象
        String token = request.getHeader("Authorization");
        // 提前设置请求继续，如果失败则修改此内容
        requestContext.setSendZuulResponse(true);
        requestContext.setResponseStatusCode(200);
        //从请求参数里获取token对象
//        if(StringUtils.isBlank((token))){
//            token  = request.getParameter("Authorization");
//        }
        // 判断是否是静态文件和验证码
        if (request.getServletPath().endsWith("/" + "exportResultStatic")) {
            return null;
        }
        if (request.getServletPath().contains("/" + "captcha")) {
            return null;
        }
        //判断是否为登录
        System.out.println(request.getServletPath());
        if (request.getServletPath().endsWith("/login/")
                || request.getServletPath().contains("/info")
                || request.getServletPath().endsWith("/register")
                || request.getServletPath().endsWith("/logout")) {
            return null;
        }
        if (request.getServletPath().endsWith("/getEmailCode")
                || request.getServletPath().endsWith("/getBackPassword")) {
            return null;
        }
//        //登录校验逻辑  根据公司情况自定义 JWT
        if (!StringUtils.isBlank(token)) {
            try {
                //判断令牌是否存在并且正确
                if (!org.springframework.util.StringUtils.isEmpty(token) && token.startsWith(tokenHead)) {
                    //获取令牌
                    String tokenKey = token.substring(tokenHead.length());
                    //根据令牌获取用户名
                    String username = jwtUtils.getUserNameFromToken(tokenKey);
                    //如果用户名不为空但是认证对象为空
                    System.out.println(SecurityContextHolder.getContext().getAuthentication() == null);
                    if (!org.springframework.util.StringUtils.isEmpty(username) && null == SecurityContextHolder.getContext().getAuthentication()) {
                        //根据用户名获取用户对象
                        UserDetails userDetails = loginServerService.getAdminByUserName(username);
                        //判断token是否有效
                        if (jwtUtils.validateToken(tokenKey, userDetails)) {
                            //给SpringSecurity全局上下文设置当前登录用户对象
                            UsernamePasswordAuthenticationToken authenticationToken =
                                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                            WebAuthenticationDetails webAuthenticationDetails =
                                    new WebAuthenticationDetailsSource().buildDetails(request);
                            authenticationToken.setDetails(webAuthenticationDetails);
                            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                            return null;
                        }
                    }
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                renderJson(requestContext, response, RespBean.noLogin());
            }
        }
        renderJson(requestContext, response, RespBean.noLogin());
        return null;
    }

    public static void renderJson(RequestContext ctx, HttpServletResponse response, Object jsonObject) {
        // 设置终止请求
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        ctx.setSendZuulResponse(false);
        ctx.getResponse().setContentType("application/json; charset=utf-8");
        ctx.setResponseBody(JSONObject.toJSONString(jsonObject));
    }

}